import type dataRs from '@ohos.data.relationalStore'
import {
  LogTag,
  _appError
} from '../01-LogManager/LogManager';
import {
  Property
} from './SqlUtil/Property';

const FileName = 'DbUtil';

export class DbUtil {
  static getType(types): string {
    let typestr;
    switch (types) {
      case 'string':
      case 'String':
        typestr = 'TEXT';
        break;
      case 'number':
      case 'Number':
        typestr = 'INTEGER';
        break;
      case 'real':
      case 'Real':
        typestr = 'REAL';
        break;
      case 'blob':
      case 'Blob':
        typestr = 'BLOB';
        break;
      default:
        typestr = 'TEXT';
    }
    return typestr
  }
}

export enum TableName {
  Mail = "mail",
  Folder = "folder",
  ContactCache = "contactCache2",
  CalendarItem = "tbCalendarItem",
  CalendarCategory = "tbCalendarCategory",
  SyncState = "tbSyncState"
}


export enum DbErrorCode {
  DuplicatePrimaryKey = 14800032
}


export function convertCursor2Entity<T>(
  fields: string[],
  properties: Record<string, Property>,
  EntityClass: new (...args: any[]) => T,
  resultSet: dataRs.ResultSet
): T[] {
  let result: T[] = [];
  const resultSetRowCount = resultSet.rowCount;
  const FunName = "convertCursor2Entity";
  const columnNameMap = new Map<string, Property>(Object.values(properties).map(item => [item.columnName, item]));
  if (resultSet.goToFirstRow()) {
    let entity = readEntity(resultSet);
    result.push(entity);
    while (resultSet.goToNextRow()) {
      let entity = readEntity(resultSet);
      result.push(entity);
    }
  } else {
    if (resultSet.rowCount > 0) {
      _appError(FileName, FunName, "", "", `resultSet row:${resultSetRowCount},but go to first row failed`)
      return result;
    }
  }
  if (resultSetRowCount !== result.length) {
    _appError(FileName, FunName, "", "", `resultSet row:${resultSetRowCount},but get entity:${result.length}`)
  }

  return result;

  function readEntity(resultSet: dataRs.ResultSet): T {
    let entity = new EntityClass();
    for (let i = 0; i < fields.length; i++) {
      try {
        let prop = columnNameMap.get(fields[i]);
        let value = getCursorValue(resultSet, prop.type, i);
        entity[prop?.name] = value;
      } catch (e) {
        _appError(FileName, FunName, "", "", `readEntity fail, key:${fields[i]}, error:${e.message}`)
      }
    }
    return entity;
  }
}


/**
 * 读取当前行指定列的数据
 * @param cursor
 * @param types
 * @param columnIndex
 * @returns
 */
function getCursorValue(cursor: dataRs.ResultSet, types: string, columnIndex: number) {
  switch (types) {
    case 'TEXT':
      return cursor.getString(columnIndex);
    case 'INTEGER':
      return cursor.getLong(columnIndex);
    case 'REAL':
      return cursor.getDouble(columnIndex);
    case 'BLOB':
      return cursor.getBlob(columnIndex);
  }
}